package com.tozed.test;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.View;
import android.util.AttributeSet;
import android.util.Log;

/**
 * ViewTouchVertical for touchpanel
*/
public class ViewTouchVertical extends ViewTouch {

    /**
    * TAG
    */
    private static final String TAG = "ViewTouchVertical";

    /**
    * Stroke width
    */
    private static final int STROKE_WIDTH = 30;
    
    /**
    * Tolerance
    */
	private static final float TOUCH_TOLERANCE_Y = 30;
	private static final float TOUCH_TOLERANCE_X = 40;
    
    /**
    * Line 1
    */
	private Path mPath11 = null;
	private Path mPath12 = null;
    
    /**
    * Line 2
    */
	private Path mPath21 = null;
	private Path mPath22 = null;
    
    /**
    * Line 3
    */
	private Path mPath31 = null;
	private Path mPath32 = null;
    
    /**
    * Line 4
    */
	private Path mPath41 = null;
	private Path mPath42 = null;
    
    /**
    * Painter
    */
	private Paint mPaint = null;
    
    /**
    * Screen width and height
    */
    private int mWidth = 0;
    private int mHeight = 0;

    /**
    * Line 1
    */
    private Point mPoint11 = new Point();
    private Point mPoint12 = new Point();
    
    /**
    * Line 2
    */
    private Point mPoint21 = new Point();
    private Point mPoint22 = new Point();
    
    /**
    * Line 3
    */
    private Point mPoint31 = new Point();
    private Point mPoint32 = new Point();
    
    /**
    * Line 4
    */
    private Point mPoint41 = new Point();
    private Point mPoint42 = new Point();
    
    
    /**
    * Touch coordination
    */
	private int mX = 0;
    private int mY = 0;

    private boolean mIsGoon = false;
    
    /**
    * Draw line orientation
    */
    private boolean mIsFromTopToBottom = true;
    
    /**
    * If line is finished
    */
    private boolean mPath1Finished = false;
    private boolean mPath2Finished = false;
    private boolean mPath3Finished = false;
    private boolean mPath4Finished = false;

    /**
    * Current line
    */
    private Path mCurrentPath1 = null;
    private Path mCurrentPath2 = null;
    private Point mCurrentPoint1 = null;
    private Point mCurrentPoint2 = null;
    private int mCurrentPathIndex = 0;

    /**
     * Constructor.
     *
     * @param context the Context, that this is running within
     */
    public ViewTouchVertical(Context context) {
        super(context);
        init();
    }

    /**
     * Constructor.
     *
     * @param context the Context, that this is running within
     * @param attrs The attributes of the XML tag that is inflating the view.
     */
    public ViewTouchVertical(Context context, AttributeSet attrs) {
   	    super(context, attrs);
        init();
   	}

    /**
     * Constructor.
     *
     * @param context the Context, that this is running within
     * @param attrs The attributes of the XML tag that is inflating the view.
     * @param defStyle The default style to apply to this view. If 0, no style
     *        will be applied (beyond what is included in the theme). This may
     *        either be an attribute resource, whose value will be retrieved
     *        from the current theme, or an explicit style resource.
     */
    public ViewTouchVertical(Context context, AttributeSet attrs, int defStyle) {
   	    super(context, attrs, defStyle);
        init();
    }

    /**
     * This is called during layout when the size of this view has changed. If
     * you were just added to the view hierarchy, you're called with the old
     * values of 0.
     *
     * @param w Current width of this view.
     * @param h Current height of this view.
     * @param oldw Old width of this view.
     * @param oldh Old height of this view.
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    	Log.v(TAG, "onSizeChanged w = " + w + " h = " + h + " oldw = " + oldw + " oldh = " + oldh);
        super.onSizeChanged(w, h, oldw, oldh);

        mWidth = (int)w;
        mHeight = (int)h;
    	Log.v(TAG, "onSizeChanged mWidth = " + mWidth + " mHeight = " + mHeight);

        /**
        * Line 1
        */
        mPoint11.set((mWidth/5), (mHeight/12));
        mPoint12.set((mWidth/5), (mHeight*11/12));
        
        /**
        * Line 2
        */
        mPoint21.set((mWidth*2/5), (mHeight/12));
        mPoint22.set((mWidth*2/5), (mHeight*11/12));
        
        /**
        * Line 3
        */
        mPoint31.set((mWidth*3/5), (mHeight/12));
        mPoint32.set((mWidth*3/5), (mHeight*11/12));
        
        /**
        * Line 4
        */
        mPoint41.set((mWidth*4/5), (mHeight/12));
        mPoint42.set((mWidth*4/5), (mHeight*11/12));
    }
    
    /**
     * Implement this to do your drawing.
     *
     * @param canvas the canvas on which the background will be drawn
     */
    @Override
    protected void onDraw(Canvas canvas) {
        Log.v(TAG, "onDraw mCurrentPathIndex = " + mCurrentPathIndex);
        drawPath1(canvas);
        drawPath2(canvas);
        drawPath3(canvas);
        drawPath4(canvas);
    }

    /**
     * Implement this method to handle touch screen motion events.
     *
     * @param event The motion event.
     * @return True if the event was handled, false otherwise.
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.v(TAG, "onTouchEvent event = " + event.getAction());
		int x = (int)event.getX();
		int y = (int)event.getY();

		switch (event.getAction()) {
    		case MotionEvent.ACTION_DOWN:
    			onActionDown(x, y);
    			//invalidate();
                return true;
    		case MotionEvent.ACTION_MOVE:
    			onActionMove(x, y);
    			//invalidate();
                return true;
    		case MotionEvent.ACTION_UP:
    			onActionUp(x, y);
    			//invalidate();
                return true;
            default:
                break;
		}

        return super.onTouchEvent(event);
    }

    /**
     * Utility 
     * For initialization
     */
    private void init() {
		mPaint = new Paint();
		mPaint.setAntiAlias(true);
		mPaint.setDither(true);
		mPaint.setColor(Color.RED);
		mPaint.setStyle(Paint.Style.STROKE);
		mPaint.setStrokeWidth(STROKE_WIDTH);

		mPath11 = new Path();
		mPath12 = new Path();
		mPath21 = new Path();
		mPath22 = new Path();
		mPath31 = new Path();
		mPath32 = new Path();
		mPath41 = new Path();
		mPath42 = new Path();
    }

    /**
     * Utility 
     * Reset path for a new draw intent 
     *
     * @param isFromTopToBottom The draw line orientation.
     */
    private void initPath(boolean isFromTopToBottom) {
        Log.v(TAG, "initPath isFromTopToBottom = " + isFromTopToBottom);
        if (isFromTopToBottom) {
            if (!mPath1Finished) {
                mPath11.reset();
                mPath12.reset();
                mPath12.moveTo(mPoint11.x, mPoint11.y);
                mPath12.lineTo(mPoint12.x, mPoint12.y);
            }
            
            if (!mPath2Finished) {
                mPath21.reset();
                mPath22.reset();
                mPath22.moveTo(mPoint21.x, mPoint21.y);
                mPath22.lineTo(mPoint22.x, mPoint22.y);
            }
            
            if (!mPath3Finished) {
                mPath31.reset();
                mPath32.reset();
                mPath32.moveTo(mPoint31.x, mPoint31.y);
                mPath32.lineTo(mPoint32.x, mPoint32.y);
            }
            
            if (!mPath4Finished) {
                mPath41.reset();
                mPath42.reset();
                mPath42.moveTo(mPoint41.x, mPoint41.y);
                mPath42.lineTo(mPoint42.x, mPoint42.y);
            }
        } else {
            if (!mPath1Finished) {
                mPath11.reset();
                mPath11.moveTo(mPoint12.x, mPoint12.y);
                mPath11.lineTo(mPoint11.x, mPoint11.y);
                mPath12.reset();
            }
            
            if (!mPath2Finished) {
                mPath21.reset();
                mPath21.moveTo(mPoint22.x, mPoint22.y);
                mPath21.lineTo(mPoint21.x, mPoint21.y);
                mPath22.reset();
            }
            
            if (!mPath3Finished) {
                mPath31.reset();
                mPath31.moveTo(mPoint32.x, mPoint32.y);
                mPath31.lineTo(mPoint31.x, mPoint31.y);
                mPath32.reset();
            }
            
            if (!mPath4Finished) {
                mPath41.reset();
                mPath41.moveTo(mPoint42.x, mPoint42.y);
                mPath41.lineTo(mPoint41.x, mPoint41.y);
                mPath42.reset();
            }
        }
    }

    /**
     * Utility 
     * Find which line has been touched 
     *
     * @param x The touch X ordination.
     * @param y The touch Y ordination.
     * @return int The line index which has been touched.
     */
    private int findPath(int x, int y) {
        Log.v(TAG, "findPath x = " + x + " y = " + y);
        mCurrentPathIndex = 0;
        if (!mPath1Finished) {
            int dx1 = Math.abs(x - mPoint11.x);
            int dy1 = Math.abs(y - mPoint11.y);
            int dx2 = Math.abs(x - mPoint12.x);
            int dy2 = Math.abs(y - mPoint12.y);
            if (dx1 <= TOUCH_TOLERANCE_X && dy1 <= TOUCH_TOLERANCE_Y) {
                mCurrentPath1 = mPath11;
                mCurrentPath2 = mPath12;
                mCurrentPoint1 = mPoint11;
                mCurrentPoint2 = mPoint12;
                mCurrentPathIndex = 1;
                mIsFromTopToBottom = true;
                Log.v(TAG, "findPath Path1 FromTopToBottom");
                return mCurrentPathIndex;
            } else if (dx2 <= TOUCH_TOLERANCE_X && dy2 <= TOUCH_TOLERANCE_Y) {
                mCurrentPath1 = mPath11;
                mCurrentPath2 = mPath12;
                mCurrentPoint1 = mPoint11;
                mCurrentPoint2 = mPoint12;
                mCurrentPathIndex = 1;
                mIsFromTopToBottom = false;
                Log.v(TAG, "findPath Path1 FromBottomToTop");
                return mCurrentPathIndex;
            }
        }

        if (!mPath2Finished) {
            int dx1 = Math.abs(x - mPoint21.x);
            int dy1 = Math.abs(y - mPoint21.y);
            int dx2 = Math.abs(x - mPoint22.x);
            int dy2 = Math.abs(y - mPoint22.y);
            if (dx1 <= TOUCH_TOLERANCE_X && dy1 <= TOUCH_TOLERANCE_Y) {
                mCurrentPath1 = mPath21;
                mCurrentPath2 = mPath22;
                mCurrentPoint1 = mPoint21;
                mCurrentPoint2 = mPoint22;
                mCurrentPathIndex = 2;
                mIsFromTopToBottom = true;
                Log.v(TAG, "findPath Path2 FromTopToBottom");
                return mCurrentPathIndex;
            } else if (dx2 <= TOUCH_TOLERANCE_X && dy2 <= TOUCH_TOLERANCE_Y) {
                mCurrentPath1 = mPath21;
                mCurrentPath2 = mPath22;
                mCurrentPoint1 = mPoint21;
                mCurrentPoint2 = mPoint22;
                mCurrentPathIndex = 2;
                mIsFromTopToBottom = false;
                Log.v(TAG, "findPath Path2 FromBottomToTop");
                return mCurrentPathIndex;
            }
        }

        if (!mPath3Finished) {
            int dx1 = Math.abs(x - mPoint31.x);
            int dy1 = Math.abs(y - mPoint31.y);
            int dx2 = Math.abs(x - mPoint32.x);
            int dy2 = Math.abs(y - mPoint32.y);
            if (dx1 <= TOUCH_TOLERANCE_X && dy1 <= TOUCH_TOLERANCE_Y) {
                mCurrentPath1 = mPath31;
                mCurrentPath2 = mPath32;
                mCurrentPoint1 = mPoint31;
                mCurrentPoint2 = mPoint32;
                mCurrentPathIndex = 3;
                mIsFromTopToBottom = true;
                Log.v(TAG, "findPath Path3 FromTopToBottom");
                return mCurrentPathIndex;
            } else if (dx2 <= TOUCH_TOLERANCE_X && dy2 <= TOUCH_TOLERANCE_Y) {
                mCurrentPath1 = mPath31;
                mCurrentPath2 = mPath32;
                mCurrentPoint1 = mPoint31;
                mCurrentPoint2 = mPoint32;
                mCurrentPathIndex = 3;
                mIsFromTopToBottom = false;
                Log.v(TAG, "findPath Path3 FromBottomToTop");
                return mCurrentPathIndex;
            }
        }

        if (!mPath4Finished) {
            int dx1 = Math.abs(x - mPoint41.x);
            int dy1 = Math.abs(y - mPoint41.y);
            int dx2 = Math.abs(x - mPoint42.x);
            int dy2 = Math.abs(y - mPoint42.y);
            if (dx1 <= TOUCH_TOLERANCE_X && dy1 <= TOUCH_TOLERANCE_Y) {
                mCurrentPath1 = mPath41;
                mCurrentPath2 = mPath42;
                mCurrentPoint1 = mPoint41;
                mCurrentPoint2 = mPoint42;
                mCurrentPathIndex = 4;
                mIsFromTopToBottom = true;
                Log.v(TAG, "findPath Path4 FromTopToBottom");
                return mCurrentPathIndex;
            } else if (dx2 <= TOUCH_TOLERANCE_X && dy2 <= TOUCH_TOLERANCE_Y) {
                mCurrentPath1 = mPath41;
                mCurrentPath2 = mPath42;
                mCurrentPoint1 = mPoint41;
                mCurrentPoint2 = mPoint42;
                mCurrentPathIndex = 4;
                mIsFromTopToBottom = false;
                Log.v(TAG, "findPath Path4 FromBottomToTop");
                return mCurrentPathIndex;
            }
        }
        
        Log.v(TAG, "findPath none Path");
        return mCurrentPathIndex;
    }

    /**
     * Utility 
     * Set a path is finished 
     */
    private void setPathFinished() {
        Log.v(TAG, "setPathFinished mCurrentPathIndex = " + mCurrentPathIndex);
        switch (mCurrentPathIndex) {
            case 1:
                mPath1Finished = true;
            break;
            case 2:
                mPath2Finished = true;
            break;
            case 3:
                mPath3Finished = true;
            break;
            case 4:
                mPath4Finished = true;
            break;
            default:
            break;
        }

        /**
        * All 4 lines are finshed notify the result
        */
        if (mPath1Finished && mPath2Finished && mPath3Finished && mPath4Finished) {
            mIsGoon = false;
            onCompletedListener listener = getOnCompletedListener();
            if (listener != null) {
                listener.onCompleted(this);
            }
        }
    }

    /**
     * Utility 
     * Draw path 
     *
     * @param canvas the canvas on which the background will be drawn
     * @param isFinished If this path is finished
     * @param point1 The left point of the line.
     * @param point2 The right point of the line.
     */
    private void drawPath(Canvas canvas, boolean isFinished, Point point1, Point point2) {
        Log.v(TAG, "drawPath isFinished = " + isFinished + " point1(" + point1.x + ", " + point1.y + ") " + " point2(" + point2.x + ", " + point2.y + ")");
        if (isFinished) {
            mPaint.setColor(Color.BLUE);
        } else {
            mPaint.setColor(Color.RED);
        }
        Path path = new Path();
        path.reset();
        path.moveTo(point1.x, point1.y);
        path.lineTo(point2.x, point2.y);
        canvas.drawPath(path, mPaint);
    }

    /**
     * Utility 
     * Draw current path 
     *
     * @param canvas the canvas on which the background will be drawn
     * @param isFinished If this path is finished
     */
    private void drawCurrentPath(Canvas canvas, boolean isFinished) {
        Log.v(TAG, "drawCurrentPath isFinished = " + isFinished + " mCurrentPoint1(" + mCurrentPoint1.x + ", " + mCurrentPoint1.y + ") " + " mCurrentPoint2(" + mCurrentPoint2.x + ", " + mCurrentPoint2.y + ")");
        if (isFinished) {
            mPaint.setColor(Color.BLUE);
            Path path = new Path();
            path.reset();
            path.moveTo(mCurrentPoint1.x, mCurrentPoint1.y);
            path.lineTo(mCurrentPoint2.x, mCurrentPoint2.y);
            canvas.drawPath(path, mPaint);
        } else {
            if (mIsFromTopToBottom) {
                if (!mCurrentPath1.isEmpty()) {
                    mPaint.setColor(Color.BLUE);
                    canvas.drawPath(mCurrentPath1, mPaint);
                }
                
                if (!mCurrentPath2.isEmpty()) {
                    mPaint.setColor(Color.RED);
                    canvas.drawPath(mCurrentPath2, mPaint);
                }
            } else {
                if (!mCurrentPath1.isEmpty()) {
                    mPaint.setColor(Color.RED);
                    canvas.drawPath(mCurrentPath1, mPaint);
                }
                
                if (!mCurrentPath2.isEmpty()) {
                    mPaint.setColor(Color.BLUE);
                    canvas.drawPath(mCurrentPath2, mPaint);
                }
            }
        }
    }

    /**
     * Utility 
     * Draw line 1 
     *
     * @param canvas the canvas on which the background will be drawn
     */
    private void drawPath1(Canvas canvas) {
        Log.v(TAG, "drawPath1 mCurrentPathIndex = " + mCurrentPathIndex);
        if (1 == mCurrentPathIndex) {
            drawCurrentPath(canvas, mPath1Finished);
        } else {
            drawPath(canvas, mPath1Finished, mPoint11, mPoint12);
        }
    }

    /**
     * Utility 
     * Draw line 2 
     *
     * @param canvas the canvas on which the background will be drawn
     */
    private void drawPath2(Canvas canvas) {
        Log.v(TAG, "drawPath2 mCurrentPathIndex = " + mCurrentPathIndex);
        if (2 == mCurrentPathIndex) {
            drawCurrentPath(canvas, mPath2Finished);
        } else {
            drawPath(canvas, mPath2Finished, mPoint21, mPoint22);
        }
    }

    /**
     * Utility 
     * Draw line 3 
     *
     * @param canvas the canvas on which the background will be drawn
     */
    private void drawPath3(Canvas canvas) {
        Log.v(TAG, "drawPath3 mCurrentPathIndex = " + mCurrentPathIndex);
        if (3 == mCurrentPathIndex) {
            drawCurrentPath(canvas, mPath3Finished);
        } else {
            drawPath(canvas, mPath3Finished, mPoint31, mPoint32);
        }
    }

    /**
     * Utility 
     * Draw line 4 
     *
     * @param canvas the canvas on which the background will be drawn
     */
    private void drawPath4(Canvas canvas) {
        Log.v(TAG, "drawPath4 mCurrentPathIndex = " + mCurrentPathIndex);
        if (4 == mCurrentPathIndex) {
            drawCurrentPath(canvas, mPath4Finished);
        } else {
            drawPath(canvas, mPath4Finished, mPoint41, mPoint42);
        }
    }

    /**
     * Utility 
     * Handle  MotionEvent.ACTION_DOWN
     *
     * @param x The touch X ordination.
     * @param y The touch Y ordination.
     */
	private void onActionDown(int x, int y) {
        Log.v(TAG, "onActionDown x = " + x + " y = " + y);
        int index = findPath(x, y);
        Log.v(TAG, "onActionDown index = " + index + " mIsFromTopToBottom = " + mIsFromTopToBottom);
        initPath(mIsFromTopToBottom);
        if (0 != index) {
            if (mIsFromTopToBottom) {
                mX = mCurrentPoint1.x;
                mY = mCurrentPoint1.y;
                Log.v(TAG, "onActionDown FromTopToBottom mX = " + mX + " mY = " + mY);
                
                mCurrentPath1.reset();
                mCurrentPath2.reset();
                mCurrentPath2.moveTo(mCurrentPoint1.x, mCurrentPoint1.y);
                mCurrentPath2.lineTo(mCurrentPoint2.x, mCurrentPoint2.y);
            } else {
                mX = mCurrentPoint2.x;
                mY = mCurrentPoint2.y;
                Log.v(TAG, "onActionDown FromBottomToTop mX = " + mX + " mY = " + mY);
                
                mCurrentPath1.reset();
                mCurrentPath1.moveTo(mCurrentPoint2.x, mCurrentPoint2.y);
                mCurrentPath1.lineTo(mCurrentPoint1.x, mCurrentPoint1.y);
                mCurrentPath2.reset();
            }
            mIsGoon = true;
            invalidate();
        } else {
            mIsGoon = false;
        }
	}

    /**
     * Utility 
     * Handle  MotionEvent.ACTION_MOVE
     *
     * @param x The touch X ordination.
     * @param y The touch Y ordination.
     */
	private void onActionMove(int x, int y) {
        Log.v(TAG, "onActionMove x = " + x + " y = " + y + " mX = " + mX + " mY = " + mY);
        if (mIsGoon) {
            int dx = Math.abs(x - mX);
            int dy = Math.abs(y - mY);
            Log.v(TAG, "onActionMove dx = " + dx + " dy = " + dy);
            
            if (mIsFromTopToBottom) {
                Log.v(TAG, "onActionMove FromTopToBottom mCurrentPoint1.x = (" + mCurrentPoint1.x + ", " +  mCurrentPoint1.y + ")");
                if (dx < TOUCH_TOLERANCE_X) {
                    mX = mCurrentPoint1.x;
                    if (y < mCurrentPoint2.y) {
                        if (Math.abs(y - mCurrentPoint2.y) < TOUCH_TOLERANCE_Y) {
                            mY = mCurrentPoint2.y;
                        } else {
                            mY = y;
                        }
                    } else {
                        mY = mCurrentPoint2.y;
                    }
                    Log.v(TAG, "onActionMove FromTopToBottom mX = " + mX + " mY = " + mY);
                    mCurrentPath1.reset();
                    mCurrentPath1.moveTo(mCurrentPoint1.x, mCurrentPoint1.y);
                    mCurrentPath1.lineTo(mX, mY);
                    Log.v(TAG, "onActionMove FromTopToBottom mCurrentPath1 from " + mCurrentPoint1.x + " to " + mX);
                
                    mCurrentPath2.reset();
                    if (mY != mCurrentPoint2.y) {
                        mCurrentPath2.moveTo(mX, mY);
                        mCurrentPath2.lineTo(mCurrentPoint2.x, mCurrentPoint2.y);
                        Log.v(TAG, "onActionMove FromTopToBottom mCurrentPath2 from " + mX + " to " + mCurrentPoint2.x);
                    } else {
                        setPathFinished();    
                    }
                } else {
                    mIsGoon = false;
                    mCurrentPath1.reset();
                    mCurrentPath2.reset();
                    mCurrentPath2.moveTo(mCurrentPoint1.x, mCurrentPoint1.y);
                    mCurrentPath2.lineTo(mCurrentPoint2.x, mCurrentPoint2.y);
                }
            } else {
                Log.v(TAG, "onActionMove FromBottomToTop mCurrentPoint2.x = (" + mCurrentPoint2.x + ", " +  mCurrentPoint2.y + ")");
                if (dx < TOUCH_TOLERANCE_X) {
                    mY = mCurrentPoint1.y;
                    if (y > mCurrentPoint1.y) {
                        if (Math.abs(y - mCurrentPoint1.y) < TOUCH_TOLERANCE_Y) {
                            mY = mCurrentPoint1.y;
                        } else {
                            if (y >= mCurrentPoint2.y) {
                                mY = mCurrentPoint2.y;
                            } else {
                                mY = y;
                            }
                        }
                    } else {
                        mY = mCurrentPoint1.y;
                    }
                    Log.v(TAG, "onActionMove FromBottomToTop mX = " + mX + " mY = " + mY);
                    mCurrentPath2.reset();
                    if (mY != mCurrentPoint2.y) {
                        mCurrentPath2.moveTo(mCurrentPoint2.x, mCurrentPoint2.y);
                        mCurrentPath2.lineTo(mX, mY);
                        Log.v(TAG, "onActionMove FromBottomToTop mCurrentPath2 from " + mCurrentPoint2.x + " to " + mX);
                    }
                    
                    mCurrentPath1.reset();
                    if (mY != mCurrentPoint1.y) {
                        mCurrentPath1.moveTo(mX, mY);
                        mCurrentPath1.lineTo(mCurrentPoint1.x, mCurrentPoint1.y);
                        Log.v(TAG, "onActionMove FromBottomToTop mCurrentPath1 from " + mX + " to " + mCurrentPoint1.x);
                    } else {
                        setPathFinished();    
                    }
                }else {
                    mIsGoon = false;
                    mCurrentPath1.reset();
                    mCurrentPath1.moveTo(mCurrentPoint2.x, mCurrentPoint2.y);
                    mCurrentPath1.lineTo(mCurrentPoint1.x, mCurrentPoint1.y);
                    mCurrentPath2.reset();
                }
            }
        }
        invalidate();
	}

    /**
     * Utility 
     * Handle  MotionEvent.ACTION_UP
     */
	private void onActionUp(int x, int y) {
        Log.v(TAG, "onActionUp x = " + x + " y = " + y);
        if (mIsGoon) {
            int dx = Math.abs(x - mX);
            int dy = Math.abs(y - mY);
            Log.v(TAG, "onActionUp dx = " + dx + " dy = " + dy);
            if (mIsFromTopToBottom) {
                Log.v(TAG, "onActionUp FromTopToBottom mCurrentPoint1.x = (" + mCurrentPoint1.x + ", " +  mCurrentPoint1.y + ")");
                if (dx < TOUCH_TOLERANCE_X) {
                    mX = mCurrentPoint1.x;
                    if (y < mCurrentPoint2.y) {
                        if (Math.abs(y - mCurrentPoint2.y) < TOUCH_TOLERANCE_Y) {
                            mY = mCurrentPoint2.y;
                        } else {
                            mY = y;
                        }
                    } else {
                        mY = mCurrentPoint2.y;
                    }
                    Log.v(TAG, "onActionUp FromTopToBottom mX = " + mX + " mY = " + mY);
                    if (mY != mCurrentPoint2.y) {
                        mCurrentPath1.reset();
                        mCurrentPath2.reset();
                        mCurrentPath2.moveTo(mCurrentPoint1.x, mCurrentPoint1.y);
                        mCurrentPath2.lineTo(mCurrentPoint2.x, mCurrentPoint2.y);
                    } else {
                        setPathFinished();    
                    }
                } else {
                    mCurrentPath1.reset();
                    mCurrentPath2.reset();
                    mCurrentPath2.moveTo(mCurrentPoint1.x, mCurrentPoint1.y);
                    mCurrentPath2.lineTo(mCurrentPoint2.x, mCurrentPoint2.y);
                }
            } else {
                Log.v(TAG, "onActionUp FromBottomToTop mCurrentPoint2.x = (" + mCurrentPoint2.x + ", " +  mCurrentPoint2.y + ")");
                if (dx < TOUCH_TOLERANCE_X) {
                    mY = mCurrentPoint1.y;
                    if (y > mCurrentPoint1.y) {
                        if (Math.abs(y - mCurrentPoint1.y) < TOUCH_TOLERANCE_Y) {
                            mY = mCurrentPoint1.y;
                        } else {
                            if (y >= mCurrentPoint2.y) {
                                mY = mCurrentPoint2.y;
                            } else {
                                mY = y;
                            }
                        }
                    } else {
                        mY = mCurrentPoint1.y;
                    }
                    Log.v(TAG, "onActionUp FromBottomToTop mX = " + mX + " mY = " + mY);
                    if (mY != mCurrentPoint1.y) {
                        mCurrentPath1.reset();
                        mCurrentPath1.moveTo(mCurrentPoint2.x, mCurrentPoint2.y);
                        mCurrentPath1.lineTo(mCurrentPoint1.x, mCurrentPoint1.y);
                        mCurrentPath2.reset();
                    } else {
                        setPathFinished();    
                    }
                }else {
                    mCurrentPath1.reset();
                    mCurrentPath1.moveTo(mCurrentPoint2.x, mCurrentPoint2.y);
                    mCurrentPath1.lineTo(mCurrentPoint1.x, mCurrentPoint1.y);
                    mCurrentPath2.reset();
                }
            }
            mIsGoon = false;
        }
        invalidate();
	}
}



